package com.smxy.daydayup.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.AbstractRequestLoggingFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Order(150)
public class LoggingRequestFilter extends AbstractRequestLoggingFilter {
    private static final Logger log = LoggerFactory.getLogger(LoggingRequestFilter.class);

    {
        setMaxPayloadLength(1024);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        HttpServletRequest requestToUse = request;
        beforeRequest(requestToUse, null);
        filterChain.doFilter(requestToUse, response);
        afterRequest(requestToUse, null);
    }

    @Override
    protected void beforeRequest(HttpServletRequest request, String message) {
        if (log.isInfoEnabled()) {
            String bodyStr = getMessagePayload(request);
            String queryString = request.getQueryString();
            log.info("curl --location --request {} '{}' {} {}",
                    request.getMethod(), StringUtils.isEmpty(queryString) ? request.getRequestURL() :
                            request.getRequestURL() + "?" + request.getQueryString(),
                    getHeaderMap(request)
                            .entrySet()
                            .stream()
                            .map(e -> String.format(" --header '%s: %s'", e.getKey(), e.getValue()))
                            .collect(Collectors.joining(" ")),
                    StringUtils.isEmpty(bodyStr) ? "" : "--data '" + bodyStr + "'");
        }
    }

    @Override
    protected void afterRequest(HttpServletRequest request, String message) {
        // to nothing
    }

    private static Map<String, String> getHeaderMap(HttpServletRequest request) {
        Enumeration<String> headerNames = request.getHeaderNames();
        Map<String, String> headerMap = new HashMap<>();

        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = request.getHeader(key);
            headerMap.put(key, value);
        }

        return headerMap;
    }

    @Value("${component.bizsafe.allowAlllog:false}")
    private Boolean allowAll;

    @Override
    public boolean shouldNotFilter(HttpServletRequest request) {
        if (allowAll) {
            return false;
        }
        String header = request.getHeader("Content-Type");
        return header == null || !header.contains("application/json");
    }
}
